<html>
<head><meta charset="utf-8"><title>Deserialization Fix · rustdoc · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/266220-rustdoc/index.html">rustdoc</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/266220-rustdoc/topic/Deserialization.20Fix.html">Deserialization Fix</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="228086101"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/266220-rustdoc/topic/Deserialization%20Fix/near/228086101" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> CraftSpider <a href="https://rust-lang.github.io/zulip_archive/stream/266220-rustdoc/topic/Deserialization.20Fix.html#228086101">(Feb 27 2021 at 22:06)</a>:</h4>
<p>For <a href="https://github.com/rust-lang/rust/issues/82299">#82299</a>, it was found that order matters for untagged enums. Fixing this could be as easy as moving the variants, but that's easy to break. The best alternative is adjacent tagging, which would match the current layout. The issue with this is that it means the <code>kind</code> would be consumed by the inner. There is a fix, but it is a little ugly. Here's my proposal:<br>
We make ItemEnum adjacently tagged. We make <code>Item::kind</code> into <code>#[serde(ignore)]</code>. We derive serialization, and manually implement deserialization to fill in <code>kind</code> based on the result of deserializing <code>inner</code>.</p>



<a name="228086173"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/266220-rustdoc/topic/Deserialization%20Fix/near/228086173" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> CraftSpider <a href="https://rust-lang.github.io/zulip_archive/stream/266220-rustdoc/topic/Deserialization.20Fix.html#228086173">(Feb 27 2021 at 22:08)</a>:</h4>
<p>This doesn't change the JSON at all, just how we implement one of the deserializations to prevent inner value conflicts. I think this is better than just moving stuff around because it also prevents a future problem with, say, <code>TypeA(String)</code> and <code>TypeB(String)</code></p>



<a name="228087799"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/266220-rustdoc/topic/Deserialization%20Fix/near/228087799" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nixon Enraght-Moony <a href="https://rust-lang.github.io/zulip_archive/stream/266220-rustdoc/topic/Deserialization.20Fix.html#228087799">(Feb 27 2021 at 22:40)</a>:</h4>
<p>I think you can do this with clever serde</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="cp">#[derive(Serialize, Deserialize, Debug)]</span><span class="w"></span>
<span class="k">struct</span> <span class="nc">Item</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">name</span>: <span class="nb">String</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="cp">#[serde(flatten)]</span><span class="w"></span>
<span class="w">    </span><span class="n">inner</span>: <span class="nc">Inner</span><span class="p">,</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="cp">#[derive(Serialize, Deserialize, Debug)]</span><span class="w"></span>
<span class="cp">#[serde(tag = </span><span class="s">"kind"</span><span class="cp">, content = </span><span class="s">"inner"</span><span class="cp">)]</span><span class="w"></span>
<span class="k">enum</span> <span class="nc">Inner</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">Struct</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">name</span>: <span class="nb">String</span><span class="p">,</span><span class="w"> </span><span class="n">n_field</span>: <span class="kt">u8</span> <span class="p">},</span><span class="w"></span>
<span class="w">    </span><span class="n">Function</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">name</span>: <span class="nb">String</span><span class="p">,</span><span class="w"> </span><span class="n">n_field</span>: <span class="kt">u8</span> <span class="p">},</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p><a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=b6cc9cb7ebee8f7aeeb3a45911fa2764">playground</a></p>
<p>This way, we remove <code>kind</code> from <code>Item</code>, and have <code>ItemEnum</code> provide both the tag and the kind</p>



<a name="228088465"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/266220-rustdoc/topic/Deserialization%20Fix/near/228088465" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> CraftSpider <a href="https://rust-lang.github.io/zulip_archive/stream/266220-rustdoc/topic/Deserialization.20Fix.html#228088465">(Feb 27 2021 at 22:53)</a>:</h4>
<p>That would work, but my goal was to keep this non-breaking, so not remove <code>kind</code> from <code>Item</code></p>



<a name="228088547"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/266220-rustdoc/topic/Deserialization%20Fix/near/228088547" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> CraftSpider <a href="https://rust-lang.github.io/zulip_archive/stream/266220-rustdoc/topic/Deserialization.20Fix.html#228088547">(Feb 27 2021 at 22:55)</a>:</h4>
<p>Otherwise that would definitely solve the problem</p>



<a name="228088629"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/266220-rustdoc/topic/Deserialization%20Fix/near/228088629" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nixon Enraght-Moony <a href="https://rust-lang.github.io/zulip_archive/stream/266220-rustdoc/topic/Deserialization.20Fix.html#228088629">(Feb 27 2021 at 22:56)</a>:</h4>
<blockquote>
<p>my goal was to keep this non-breaking,</p>
</blockquote>
<p>Why, breaking to whom?</p>
<p>The json output is uneffected, and the rust types are not exported anywhere</p>



<a name="228088748"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/266220-rustdoc/topic/Deserialization%20Fix/near/228088748" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> CraftSpider <a href="https://rust-lang.github.io/zulip_archive/stream/266220-rustdoc/topic/Deserialization.20Fix.html#228088748">(Feb 27 2021 at 22:59)</a>:</h4>
<p>That's true. And overall I don't think there's a problem with removing the kind, as I think the common cases you want to match on inner anyways. I'd like <span class="user-mention" data-user-id="229913">@HeroicKatora</span>'s input on this, as they're the main consumer and I believe have started copying over the rustdoc types (The goal is once rustdoc-json stabilizes, the types become part of the public interface. That's why I was thinking of a change to them as 'breaking')</p>



<a name="228088865"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/266220-rustdoc/topic/Deserialization%20Fix/near/228088865" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nixon Enraght-Moony <a href="https://rust-lang.github.io/zulip_archive/stream/266220-rustdoc/topic/Deserialization.20Fix.html#228088865">(Feb 27 2021 at 23:01)</a>:</h4>
<p>Yeah, one day we should put <code>rustdoc-json-types</code> on <a href="http://crates.io">crates.io</a>, (posibly before the format stabilizes, and only release 1.0 when rustdoc-json hits stable), but untill then, we should absolutly make breaking changes to the types</p>



<a name="228088927"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/266220-rustdoc/topic/Deserialization%20Fix/near/228088927" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> CraftSpider <a href="https://rust-lang.github.io/zulip_archive/stream/266220-rustdoc/topic/Deserialization.20Fix.html#228088927">(Feb 27 2021 at 23:02)</a>:</h4>
<p>Yeah, I've definitely been making breaking changes already too. Now is the time to make them :P</p>



<a name="228088942"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/266220-rustdoc/topic/Deserialization%20Fix/near/228088942" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> CraftSpider <a href="https://rust-lang.github.io/zulip_archive/stream/266220-rustdoc/topic/Deserialization.20Fix.html#228088942">(Feb 27 2021 at 23:02)</a>:</h4>
<p>I just always make sure to bump version when I do. Anyways, if removing <code>kind</code> and just exposing inner as a tagged enum works, that's definitely the cleanest solution.</p>



<a name="228089178"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/266220-rustdoc/topic/Deserialization%20Fix/near/228089178" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/266220-rustdoc/topic/Deserialization.20Fix.html#228089178">(Feb 27 2021 at 23:06)</a>:</h4>
<p>Sounds like a plan to me :)</p>



<a name="228094013"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/266220-rustdoc/topic/Deserialization%20Fix/near/228094013" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> HeroicKatora <a href="https://rust-lang.github.io/zulip_archive/stream/266220-rustdoc/topic/Deserialization.20Fix.html#228094013">(Feb 28 2021 at 00:47)</a>:</h4>
<p>The <code>#[serde(flatten)] inner</code> solution looks neat, especially if it leaves the current json structure in place. I'm not dependent on the files in rustdoc-json as of yet, just the json structure.</p>



<a name="228094092"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/266220-rustdoc/topic/Deserialization%20Fix/near/228094092" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> HeroicKatora <a href="https://rust-lang.github.io/zulip_archive/stream/266220-rustdoc/topic/Deserialization.20Fix.html#228094092">(Feb 28 2021 at 00:48)</a>:</h4>
<p>So, making breaking changes in those types is fine. Even breaking the format is not usually a problem. Note that I've customized the types anyways since in my code the <code>version</code> field is replaced by one that asserts the expected version :)</p>



<a name="228094224"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/266220-rustdoc/topic/Deserialization%20Fix/near/228094224" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> CraftSpider <a href="https://rust-lang.github.io/zulip_archive/stream/266220-rustdoc/topic/Deserialization.20Fix.html#228094224">(Feb 28 2021 at 00:51)</a>:</h4>
<p>Opened <a href="https://github.com/rust-lang/rust/issues/82613">#82613</a> with the proposed flatten fix</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>